package cn.xydpeng.springframework.context.event;

import cn.xydpeng.springframework.beans.factory.BeanFactory;
import cn.xydpeng.springframework.context.ApplicationEvent;
import cn.xydpeng.springframework.context.ApplicationListener;
import cn.xydpeng.springframework.core.ResolvableType;
import cn.xydpeng.springframework.lang.Nullable;

import java.util.Collection;
import java.util.concurrent.Executor;

/**
 * @author xydpeng
 * @version v1.0
 * @date: 2022/10/21
 * @description:
 */
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    @Nullable
    private Executor taskExecutor;

    public SimpleApplicationEventMulticaster() {
    }

    public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
        setBeanFactory(beanFactory);
    }


    @Override
    public void multicastEvent(ApplicationEvent event) {
        multicastEvent(event, ResolvableType.forInstance(event));
    }

    @Override
    public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
        Collection<ApplicationListener> listeners = getApplicationListeners(event,eventType);
        Executor executor = getTaskExecutor();
        for (ApplicationListener listener : listeners) {
            if (executor != null) {
                executor.execute(() -> {
                    invokeListener(listener, event);
                });
            } else {
                invokeListener(listener, event);
            }
        }
    }

    protected Executor getTaskExecutor() {
        return taskExecutor;
    }

    protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
        listener.onApplicationEvent(event);
    }
}
